import base64

from functional import seq
from odoo.addons.fastapi_odoo_bridge.core.token import JWTUtils
from odoo.addons.basic_configuration.functions.rp_pay_interface import RpPayInterface
from odoo.addons.rp_customer_management.functions.customer_functions import CustomerFunctions
from odoo.addons.basic_configuration.functions.logger import log

"""
新UI的中心逻辑
"""


class CenterAreaFunc(object):
    """
    Description:中心相关的逻辑【隐私条款，帮助中心，用户中心】
    """

    def __init__(self, env):
        self.env = env

    """
    隐私条款相关
    """

    def get_compliance_and_agreements(self, type):
        """
        获取条款文章
        """
        mapping = [(1, 'terms_and_condition'), (2, 'cookie_policy',), (3, 'legal_notice'), (4, 'prohibited_goods')]
        type_name = None
        for key, value in mapping:
            if key == type:
                type_name = value
        if not type_name:
            return {
                'code': 400,
                'msg': 'type参数错误',
                'data': []
            }
        compliance_and_agreements_id = self.env['rp.compliance.and.user.agreements'].search([('type', '=', type_name), ('state', '=', 'publish')])
        return compliance_and_agreements_id

    """
    Q&A帮助中心
    """

    def get_question_and_answer_keyword(self):
        """
        获取Q&A所有关键字
        """
        question_and_keyword_ids = self.env['rp.question.answer.keyword'].search([])
        if not question_and_keyword_ids:
            return {
                'code': 400,
                'msg': '没有关键字信息',
                'data': []
            }
        return question_and_keyword_ids

    def get_question_and_answer_list(self, filter_params):
        """
        获取帮助中心关键字列表
        """
        # 获取筛选条件
        name = filter_params.name.strip() if filter_params.name else None
        key_word_ids = filter_params.key_word if filter_params.key_word else []
        domain_list = []
        if name:
            domain_list.append(('name', 'ilike', f'%{name}%'))
        question_and_answer_ids = self.env['rp.question.and.answer'].search(domain_list)
        if key_word_ids:
            question_and_answer_ids = question_and_answer_ids.filtered(lambda r: set(r.keywords_ids.ids) & set(key_word_ids))
        if not question_and_answer_ids:
            return {
                'code': 400,
                'msg': '没有找到第一等级的Q&A',
                'data': []
            }
        return question_and_answer_ids

    def get_one_question_and_answer_detail(self, question_answer_id):
        """
        获取Q&A问答文章详情
        """
        rp_question_and_answer_id = self.env['rp.question.and.answer'].search([('id', '=', question_answer_id)])
        if not rp_question_and_answer_id:
            return {
                'code': 400,
                'msg': '没有找到对应的Q&A信息',
                'data': []
            }
        return rp_question_and_answer_id

    """
    个人中心相关
    """

    def get_user_info(self, user_id):
        """
        获取用户信息
        """
        rp_customer_id = self.env['rp.customer'].search([('id', '=', user_id)])
        if not rp_customer_id:
            return {
                'code': 400,
                'msg': '没有此用户',
                'data': []
            }
        return rp_customer_id

    def edit_user_info(self, user_info):
        """
        编辑用户信息
        """
        # 获取信息
        id = user_info.id
        first_name = user_info.first_name
        last_name = user_info.last_name
        # TODO 邮箱单独修改
        area_code = user_info.area_code
        phone = user_info.phone
        # 更新数据
        rp_customer_id = self.env['rp.customer'].search([('id', '=', id)])
        if not rp_customer_id:
            return {
                'code': 400,
                'msg': '没有找到该用户',
                'data': []
            }
        values = {
            'first_name': first_name,
            'last_name': last_name,
            'phone_number': '+' + area_code + ' ' + phone,
            'area_code': area_code
        }
        rp_customer_id.write(values)
        return {
            'code': 200,
            'msg': '修改成功',
            'data': []
        }

    def delete_user_account(self, user_id):
        """
        删除用户信息
        """
        rp_customer_id = self.env['rp.customer'].search([('id', '=', user_id)])
        if not rp_customer_id:
            return {
                'code': 400,
                'msg': '没有找到该用户',
                'data': []
            }
        rp_customer_id.write({'active': False})
        return {
            'code': 200,
            'msg': '删除该用户成功',
            'data': []
        }

    def obtain_user_balance(self, user_id):
        """
        获取用户余额
        """
        rp_customer_balance_id = self.env['rp.customer.balance'].search([('rp_customer_id', '=', user_id)], limit=1)
        if not rp_customer_balance_id:
            return {
                'code': 400,
                'msg': '没有找到该用户余额',
                'data': []
            }
        return rp_customer_balance_id

    def pop_up_user_balance(self, pop_up, request):
        """
        充值用户余额
        Params:
        -pop_up:充值
        -request:Request对象
        """
        # 获取充值参数

        user_id = pop_up.user_id
        customer_id = request.session.get('order_customer_id')
        # 获取token
        token_str = request.headers['Authorization']
        if user_id != int(customer_id):
            return {
                'code': 403,
                'msg': '不允许充值非登录用户的信息',
                'data': []
            }
        amount = pop_up.amount
        pay_type = pop_up.pay_type
        # 查询用户余额记录
        rp_customer_balance_id = self.env['rp.customer.balance'].search([('rp_customer_id', '=', user_id)])
        if pay_type != 1:
            return {
                'code': 403,
                'msg': '暂不支持此种支付方式',
                'data': []
            }
        if not rp_customer_balance_id:
            return {
                'code': 400,
                'msg': '需要后台创建用户余额',
                'data': []
            }
        params = '?customer_id={}&amount={}&Authorization={}'.format(str(user_id), str(int(amount)), token_str)
        url = RpPayInterface(self.env).action_to_pay(strategy='Stripe', pay_price=amount, success_basic_path='/web_api_new/user_route/pop_up/check/success', error_basic_path='/web_api_new/user_route/pop_up/check/cancel', params=params)
        return {
            'code': 200,
            'msg': '生成支付链接成功',
            'data': url
        }

    def modify_user_password(self, user_security):
        """
        修改用户密码
        """
        user_id = user_security.user_id
        user_name = user_security.user_name
        old_password = user_security.old_password
        new_password = user_security.new_password
        # 创建JWT集成对象
        jwt_utils = JWTUtils(model='rp.customer')
        jwt_utils.create_crypt_context()
        jwt_utils.create_oauth2_schema('/modify/user/password')
        jwt_utils.env = self.env
        try:
            user = jwt_utils.authenticate_user(user_name.strip(), old_password.strip())
        except Exception:
            return {
                'code': '403',
                'msg': '输入的旧密码与用户名不匹配',
                'data': []
            }
        # 校验通过可以进行修改密码
        if user:
            rp_customer_id = self.env['rp.customer'].search([('id', '=', user_id)])
            if rp_customer_id.username.strip() != user_name.strip():
                return {
                    'code': 403,
                    'msg': '传入的用户ID和用户名不匹配',
                    'data': []
                }
            password = jwt_utils.encrypt_password(plain_password=new_password)
            rp_customer_id.write({'password': password})
        return {
            'code': 200,
            'msg': '密码修改成功',
            'data': []
        }

    def upload_profile(self, profile, user_id):
        """
        上传用户头像
        """
        rp_customer_id = self.env['rp.customer'].search([('id', '=', user_id)])
        if not rp_customer_id:
            return {
                'code': 400,
                'msg': '没有找到该用户',
                'data': []
            }
        base64_data = base64.b64encode(profile.file.read()).decode()
        # 如果该用户下有附件，先删除附件
        ir_attachment_id = self.env['ir.attachment'].search([('res_id', '=', rp_customer_id.id), ('res_field', '=', 'profile_image')])
        if ir_attachment_id:
            ir_attachment_id.unlink()
        # 触发保存至附件的逻辑
        rp_customer_id.with_context({'upload': True, 'res_model': 'rp.customer', 'file_name': profile.filename}).write({'profile_image': base64_data})
        profile_id = self.env['ir.attachment'].search([('res_id', '=', rp_customer_id.id), ('res_field', '=', 'profile_image')])
        # 查看用户的附件信息
        return {
            'code': 200,
            'msg': '上传成功',
            'data': profile_id.url
        }

    def get_user_order_list(self, user_id, order_state, page, page_size, order_by):
        """
        获取用户所有的订单
        """
        domain_list = [('active', '=', True)]
        if user_id:
            domain_list.append(('customer_id', '=', user_id))
        if order_state == 1:
            domain_list.append(('state', '=', 'unpaid'))
        if order_state == 2:
            domain_list.append(('state', 'in', ['done', 'invoiced']))
        # 获取偏移量和每页条数
        rp_ship_order_all_ids = self.env['rp.ship.order'].search(domain=domain_list)
        offset = (page - 1) * page_size
        rp_ship_order_ids = self.env['rp.ship.order'].search(domain=domain_list, offset=offset, limit=page_size, order=order_by)
        # 触发支付单计算逻辑
        rp_payment_ids = self.env['rp.payment'].search([('advance_document_id.field_name_id.model', '=', 'rp.ship.order'), ('advance_document_id.field_record_id', 'in', rp_ship_order_ids.ids)])
        for record in rp_payment_ids:
            record.compute_expired_time_and_behind_process()
        return rp_ship_order_ids, len(rp_ship_order_all_ids.ids)

    def get_order_detail(self, order_id):
        """
        根据订单ID获取订单
        """
        rp_ship_order = self.env['rp.ship.order'].search([('id', '=', order_id)])
        return rp_ship_order

    def get_shipment_label(self, shipment_id, order_id):
        """
        获取运单面单
        """
        rp_shipment_id = self.env['rp.shipment'].search([('id', '=', shipment_id), ('rp_ship_order_id', '=', order_id)])
        if not rp_shipment_id:
            return {
                'code': 400,
                'msg': '传递参数有误，未找到匹配的运输单',
                'data': []
            }
        ir_attachment_ids = self.env['ir.attachment'].search([('res_id', '=', shipment_id), ('res_model', '=', 'rp.shipment')])
        url_list = seq(ir_attachment_ids).map(lambda r: r.url).to_list()
        preview_url_list = seq(ir_attachment_ids).map(lambda r: r.preview_url).to_list()
        return {
            'url': url_list,
            'preview_url': preview_url_list
        }

    def ger_user_address_book(self, user_id):
        """
        根据用户ID获取地址
        """
        rp_customer_id = self.env['rp.customer'].search([('id', '=', user_id)])
        if not rp_customer_id:
            return {
                'code': 400,
                'msg': '找不到该用户',
                'data': []
            }
        return rp_customer_id.address_ids

    def edit_or_save_address_book(self, address, user_id):
        """
        编辑或保存地址
        """
        # 获取数据
        id = address.id
        rel_type = address.rel_type
        default_address = address.default_address
        address_type = address.address_type
        contact_company_name = address.contact_company_name
        last_name = address.last_name
        first_name = address.first_name
        area_code = address.area_code
        mobile = address.mobile
        street = address.street
        street2 = address.street2
        email = address.email
        postal_code_id = address.postal_code
        edit_tag = address.edit_tag

        # 查询用户
        rp_customer_id = self.env['rp.customer'].search([('id', '=', user_id)])
        if not rp_customer_id:
            return {
                'code': 400,
                'msg': '没有找到用户数据',
                'data': []
            }

        values = {
            'rel_type': rel_type,
            'default_address': default_address,
            'address_type': address_type,
            'contact_company_name': contact_company_name,
            'last_name': last_name,
            'first_name': first_name,
            'area_code': area_code,
            'mobile': mobile,
            'street': street,
            'street2': street2,
            'email': email,
            'name': last_name + ' ' + first_name,
            'postal_code_id': postal_code_id,
            'customer_address_id': rp_customer_id.id
        }
        if edit_tag:
            if not id:
                return {
                    'code': 400,
                    'msg': '编辑地址必须带地址ID',
                    'data': []
                }
            res_partner = self.env['res.partner'].search([('id', '=', id)])
            if res_partner.customer_address_id.id != user_id:
                return {
                    'code': 400,
                    'msg': '传递的地址不属于该用户'
                }

            # 更新数据
            res_partner.write(values)
            res_partner._onchange_postal_code()
            res_partner._check_duplicates()
            res_partner.write({'postal_code_id': postal_code_id})
        else:
            address_id = self.env['res.partner'].create(values)
            address_id._onchange_postal_code()
            address_id._check_duplicates()
            address_id.write({'postal_code_id': postal_code_id})
        return {
            'code': 200,
            'msg': '编辑地址成功' if edit_tag else '添加地址成功',
            'data': []
        }

    def delete_address_book(self, address_id):
        """
        逻辑删除某一项地址
        """
        res_partner_id = self.env['res.partner'].search([('id', '=', address_id)])
        if not res_partner_id:
            return {
                'code': 400,
                'msg': '该地址不存在',
                'data': []
            }
        res_partner_id.write({'active': False})
        return {
            'code': 200,
            'msg': '地址删除成功',
            'data': []
        }

    def obtain_user_invoice_list(self, user_id):
        """
        获取用户发票
        Params:
        -user_id:用户ID
        """
        rp_customer_id = self.env['rp.customer'].browse()
        if user_id:
            rp_customer_id = self.env['rp.customer'].search([('id', '=', user_id)])
            log('用户名称：{}，用户ID：{}'.format(rp_customer_id.name, rp_customer_id.id))
        if not rp_customer_id or not user_id:
            return {
                'code': '400',
                'msg': '没有找到该用户',
                'data': []
            }
        rp_customer_model_id = self.env['ir.model'].search([('model', '=', 'rp.customer')])
        log('用户模型ID：{}'.format(rp_customer_model_id.id))
        rp_finance_invoice_ids = self.env['rp.finance.invoice'].search([('customer_id.field_name_id', '=', rp_customer_model_id.id), ('customer_id.field_record_id', '=', user_id)])
        log('查到的发票列表是：{}'.format(rp_finance_invoice_ids.mapped(lambda r: r.code)))
        log('发票列表所属的用户是：{}'.format(rp_finance_invoice_ids.mapped(lambda r: r.customer_id.field_record_id)))
        return rp_finance_invoice_ids

    def top_up_check_success(self, customer_id, amount, env):
        """
        充值回调函数
        Params:
        -customer_id:客户ID
        -amount:充值金额
        """

        # 查询客户
        rp_customer_id = self.env['rp.customer'].search([('id', '=', customer_id)])
        rp_customer_balance_id = rp_customer_id.rp_customer_balance_id
        if not rp_customer_id or not rp_customer_balance_id:
            return {
                'code': 400,
                'msg': '没有找到该客户或客户余额记录不存在',
                'data': []
            }
        # 获取参数，充值只用于增加实付金额部分
        actual_price = rp_customer_balance_id.actual_price + amount
        present_price = rp_customer_balance_id.present_price
        rp_customer_balance_id.write({
            'actual_price': actual_price,
            'present_price': present_price
        })
        # 更新金额
        CustomerFunctions(env).pop_up(rp_customer_balance_id)

    """
    邀请推广相关
    """

    def get_or_filter_coupon(self, coupon_filter):
        """
        获取或过滤优惠券
        """

        # 获取请求参数
        user_id = coupon_filter.user_id
        coupon_type = coupon_filter.coupon_type
        coupon_state = coupon_filter.coupon_state
        order_by = ','.join(coupon_filter.order_by)
        page = coupon_filter.page
        page_size = coupon_filter.page_size
        tag = coupon_filter.tag

        # 获取优惠券
        domain_list = [('rp_customer_id', '=', user_id)]
        if tag:
            if coupon_type:
                domain_list.append(('coupon_type', '=', coupon_type))
            if coupon_state:
                domain_list.append(('rp_coupon_status', '=', coupon_state))
        coupon_ids = self.env['rp.customer.coupon'].search(domain=domain_list, offset=(page - 1) * page_size, limit=page_size, order=order_by)
        return coupon_ids
